<script setup lang="ts">
import type {
  AttributeBag,
  AttributesFacet,
} from '#/api/resource-center/types';

import { computed, reactive, ref } from 'vue';

import { IconifyIcon } from '@vben/icons';

import { message } from 'ant-design-vue';

// Props
interface Props {
  attributes?: AttributesFacet;
}

const props = defineProps<Props>();

// Emits
const emit = defineEmits<{
  update: [attributes: AttributesFacet];
}>();

// 响应式数据
const bagModalVisible = ref(false);
const previewModalVisible = ref(false);
const editingBag = ref<AttributeBag | null>(null);
const previewBagData = ref<AttributeBag | null>(null);
const propertyKeys = ref<Record<string, string>>({});
const valueKeys = ref<Record<string, string>>({});

// 表单数据
const bagForm = reactive({
  id: '',
  domain: '',
  schema: {
    type: 'object',
    properties: {} as Record<string, any>,
  },
  values: {} as Record<string, any>,
});

// 表单验证规则
const bagRules = {
  id: [{ required: true, message: '请输入属性包ID' }],
  domain: [{ required: true, message: '请选择域' }],
};

// 计算属性
const attributes = computed(() => props.attributes || { bags: [] });

// 方法
const showAddBagModal = () => {
  editingBag.value = null;
  resetBagForm();
  bagModalVisible.value = true;
};

const editBag = (bag: AttributeBag) => {
  editingBag.value = bag;
  bagForm.id = bag.id;
  bagForm.domain = bag.domain;
  bagForm.schema = { ...bag.schema };
  bagForm.values = { ...bag.values };

  // 初始化键名映射
  propertyKeys.value = {};
  valueKeys.value = {};
  Object.keys(bagForm.schema.properties || {}).forEach((key) => {
    propertyKeys.value[key] = key;
  });
  Object.keys(bagForm.values || {}).forEach((key) => {
    valueKeys.value[key] = key;
  });

  bagModalVisible.value = true;
};

const showPreviewBag = (bag: AttributeBag) => {
  previewBagData.value = bag;
  previewModalVisible.value = true;
};

const deleteBag = (bagId: string) => {
  const newBags =
    attributes.value.bags?.filter((bag) => bag.id !== bagId) || [];
  emit('update', { ...attributes.value, bags: newBags });
  message.success('属性包删除成功');
};

const saveBag = () => {
  const newBag: AttributeBag = {
    id: bagForm.id,
    domain: bagForm.domain,
    schema: { ...bagForm.schema },
    values: { ...bagForm.values },
  };

  const currentBags = attributes.value.bags || [];
  let newBags: AttributeBag[];
  newBagsnewBags;

  if (editingBag.value) {
    // 编辑模式
    newBags = currentBags.map((bag) =>
      bag.id === editingBag.value!.id ? newBag : bag,
    );
  } else {
    // 新增模式
    newBags = [...currentBags, newBag];
  }

  emit('update', { ...attributes.value, bags: newBags });
  message.success(editingBag.value ? '属性包更新成功' : '属性包创建成功');
  bagModalVisible.value = false;
};

const cancelBag = () => {
  bagModalVisible.value = false;
  resetBagForm();
};

const resetBagForm = () => {
  bagForm.id = '';
  bagForm.domain = '';
  bagForm.schema = { type: 'object', properties: {} };
  bagForm.values = {};
  propertyKeys.value = {};
  valueKeys.value = {};
};

const getPropertyCount = (bag: AttributeBag) => {
  return Object.keys(bag.schema?.properties || {}).length;
};

// Schema编辑器方法
const addSchemaProperty = () => {
  const key = `property_${Date.now()}`;
  bagForm.schema.properties[key] = {
    type: 'string',
    description: '',
    required: false,
  };
  propertyKeys.value[key] = key;
};

const removeSchemaProperty = (key: string) => {
  delete bagForm.schema.properties[key];
  delete propertyKeys.value[key];
};

const updatePropertyKey = (oldKey: string) => {
  const newKey = propertyKeys.value[oldKey];
  if (newKey && newKey !== oldKey) {
    bagForm.schema.properties[newKey] = bagForm.schema.properties[oldKey];
    delete bagForm.schema.properties[oldKey];
    propertyKeys.value[newKey] = newKey;
    delete propertyKeys.value[oldKey];
  }
};

// 值编辑器方法
const addValue = () => {
  const key = `value_${Date.now()}`;
  bagForm.values[key] = '';
  valueKeys.value[key] = key;
};

const removeValue = (key: string) => {
  delete bagForm.values[key];
  delete valueKeys.value[key];
};

const updateValueKey = (oldKey: string) => {
  const newKey = valueKeys.value[oldKey];
  if (newKey && newKey !== oldKey) {
    bagForm.values[newKey] = bagForm.values[oldKey];
    delete bagForm.values[oldKey];
    valueKeys.value[newKey] = newKey;
    delete valueKeys.value[oldKey];
  }
};
</script>

<template>
  <div class="resource-attributes">
    <!-- 属性包管理 -->
    <div class="attributes-header">
      <h3>属性包管理</h3>
      <a-button type="primary" @click="showAddBagModal">
        <template #icon>
          <IconifyIcon icon="ant-design:plus-outlined" />
        </template>
        新增属性包
      </a-button>
    </div>

    <!-- 属性包列表 -->
    <div class="attributes-content">
      <a-empty v-if="!attributes?.bags?.length" description="暂无属性包" />

      <div v-else class="bags-container">
        <a-card
          v-for="bag in attributes.bags"
          :key="bag.id"
          class="bag-card"
          :title="bag.domain"
        >
          <template #extra>
            <a-space>
              <a-button type="link" size="small" @click="editBag(bag)">
                编辑
              </a-button>
              <a-button type="link" size="small" @click="showPreviewBag(bag)">
                预览
              </a-button>
              <a-popconfirm
                title="确定要删除这个属性包吗？"
                @confirm="deleteBag(bag.id)"
              >
                <a-button type="link" size="small" danger>删除</a-button>
              </a-popconfirm>
            </a-space>
          </template>
          <div class="bag-info">
            <p><strong>ID:</strong> {{ bag.id }}</p>
            <p><strong>域:</strong> {{ bag.domain }}</p>
            <p><strong>属性数量:</strong> {{ getPropertyCount(bag) }}</p>
          </div>

          <!-- 属性值预览 -->
          <div
            v-if="bag.values && Object.keys(bag.values).length > 0"
            class="values-preview"
          >
            <h4>当前值</h4>
            <a-descriptions :column="2" size="small">
              <a-descriptions-item
                v-for="(value, key) in bag.values"
                :key="key"
                :label="key"
              >
                <span v-if="Array.isArray(value)" class="array-value">
                  {{ value.join(', ') }}
                </span>
                <span v-else>{{ value }}</span>
              </a-descriptions-item>
            </a-descriptions>
          </div>
        </a-card>
      </div>
    </div>

    <!-- 新增/编辑属性包模态框 -->
    <a-modal
      v-model:open="bagModalVisible"
      :title="editingBag ? '编辑属性包' : '新增属性包'"
      width="800px"
      @ok="saveBag"
      @cancel="cancelBag"
    >
      <a-form
        ref="bagFormRef"
        :model="bagForm"
        :rules="bagRules"
        layout="vertical"
      >
        <a-row :gutter="16">
          <a-col :span="12">
            <a-form-item label="属性包ID" name="id">
              <a-input
                v-model:value="bagForm.id"
                placeholder="请输入属性包ID"
                :disabled="!!editingBag"
              />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item label="域" name="domain">
              <a-select
                v-model:value="bagForm.domain"
                placeholder="请选择域"
                allow-clear
              >
                <a-select-option value="BUSINESS">业务域</a-select-option>
                <a-select-option value="TECHNICAL">技术域</a-select-option>
                <a-select-option value="OPERATIONAL">运营域</a-select-option>
                <a-select-option value="COMPLIANCE">合规域</a-select-option>
                <a-select-option value="ABILITY">能力域</a-select-option>
                <a-select-option value="RESOURCE">资源域</a-select-option>
              </a-select>
            </a-form-item>
          </a-col>
        </a-row>

        <!-- Schema编辑器 -->
        <a-form-item label="Schema定义" name="schema">
          <div class="schema-editor">
            <a-button @click="addSchemaProperty" type="dashed" block>
              <IconifyIcon icon="ant-design:plus-outlined" />
              添加属性定义
            </a-button>

            <div v-if="bagForm.schema.properties" class="schema-properties">
              <div
                v-for="(prop, key) in bagForm.schema.properties"
                :key="key"
                class="property-item"
              >
                <a-row :gutter="8">
                  <a-col :span="6">
                    <a-input
                      v-model:value="propertyKeys[key]"
                      placeholder="属性名"
                      @change="updatePropertyKey(key)"
                    />
                  </a-col>
                  <a-col :span="4">
                    <a-select v-model:value="prop.type" placeholder="类型">
                      <a-select-option value="string">字符串</a-select-option>
                      <a-select-option value="number">数字</a-select-option>
                      <a-select-option value="boolean">布尔值</a-select-option>
                      <a-select-option value="array">数组</a-select-option>
                      <a-select-option value="object">对象</a-select-option>
                    </a-select>
                  </a-col>
                  <a-col :span="8">
                    <a-input
                      v-model:value="prop.description"
                      placeholder="描述"
                    />
                  </a-col>
                  <a-col :span="4">
                    <a-checkbox v-model:checked="prop.required">
                      必填
                    </a-checkbox>
                  </a-col>
                  <a-col :span="2">
                    <a-button
                      type="text"
                      danger
                      @click="removeSchemaProperty(key)"
                    >
                      <IconifyIcon icon="ant-design:delete-outlined" />
                    </a-button>
                  </a-col>
                </a-row>
              </div>
            </div>
          </div>
        </a-form-item>

        <!-- 属性值编辑器 -->
        <a-form-item label="属性值" name="values">
          <div class="values-editor">
            <a-button @click="addValue" type="dashed" block>
              <IconifyIcon icon="ant-design:plus-outlined" />
              添加属性值
            </a-button>

            <div v-if="bagForm.values" class="values-list">
              <div
                v-for="(value, key) in bagForm.values"
                :key="key"
                class="value-item"
              >
                <a-row :gutter="8">
                  <a-col :span="6">
                    <a-input
                      v-model:value="valueKeys[key]"
                      placeholder="属性名"
                      @change="updateValueKey(key)"
                    />
                  </a-col>
                  <a-col :span="12">
                    <a-input
                      v-model:value="bagForm.values[key]"
                      placeholder="属性值"
                    />
                  </a-col>
                  <a-col :span="4">
                    <a-button type="text" danger @click="removeValue(key)">
                      <IconifyIcon icon="ant-design:delete-outlined" />
                    </a-button>
                  </a-col>
                </a-row>
              </div>
            </div>
          </div>
        </a-form-item>
      </a-form>
    </a-modal>

    <!-- 属性包预览模态框 -->
    <a-modal
      v-model:open="previewModalVisible"
      title="属性包预览"
      width="600px"
      :footer="null"
    >
      <div v-if="previewBagData" class="bag-preview">
        <a-descriptions title="基本信息" :column="2">
          <a-descriptions-item label="ID">
            {{ previewBagData.id }}
          </a-descriptions-item>
          <a-descriptions-item label="域">
            {{ previewBagData.domain }}
          </a-descriptions-item>
        </a-descriptions>

        <a-divider />

        <a-descriptions title="Schema定义" :column="1">
          <a-descriptions-item label="JSON Schema">
            <pre class="schema-json">{{
              JSON.stringify(previewBagData.schema, null, 2)
            }}</pre>
          </a-descriptions-item>
        </a-descriptions>

        <a-divider />

        <a-descriptions title="当前值" :column="1">
          <a-descriptions-item label="属性值">
            <pre class="values-json">{{
              JSON.stringify(previewBagData.values, null, 2)
            }}</pre>
          </a-descriptions-item>
        </a-descriptions>
      </div>
    </a-modal>
  </div>
</template>

<style lang="less" scoped>
.resource-attributes {
  .attributes-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;

    h3 {
      margin: 0;
    }
  }

  .attributes-content {
    .bags-container {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
      gap: 16px;
    }

    .bag-card {
      .bag-info {
        margin-bottom: 12px;

        p {
          margin: 4px 0;
        }
      }

      .values-preview {
        h4 {
          margin: 0 0 8px 0;
          font-size: 14px;
          font-weight: 600;
        }

        .array-value {
          color: #1890ff;
        }
      }
    }
  }

  .schema-editor,
  .values-editor {
    .schema-properties,
    .values-list {
      margin-top: 12px;

      .property-item,
      .value-item {
        margin-bottom: 8px;
        padding: 8px;
        border: 1px solid #f0f0f0;
        border-radius: 4px;
        background: #fafafa;
      }
    }
  }

  .bag-preview {
    .schema-json,
    .values-json {
      background: #f5f5f5;
      padding: 8px;
      border-radius: 4px;
      font-size: 12px;
      font-family: monospace;
      white-space: pre-wrap;
      word-break: break-all;
      max-height: 200px;
      overflow: auto;
    }
  }
}
</style>
